package com.songqi.common.web.request.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.zxing.BarcodeFormat;
import com.songqi.common.core.domain.R;
import com.songqi.common.core.domain.page.PageDomain;
import com.songqi.common.core.domain.page.PageDataInfo;
import com.songqi.common.core.utils.BeanCopyUtil;
import com.songqi.common.core.utils.ServletUtils;
import com.songqi.common.core.utils.SqlStrUtil;
import com.songqi.common.core.utils.StringUtils;
import com.songqi.common.security.model.LoginUser;
import com.songqi.common.security.service.TokenService;
import com.songqi.common.security.service.TokenUser;
import com.songqi.common.web.request.util.TableSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.beans.PropertyEditorSupport;
import java.io.*;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;

/**
 * web层通用数据处理
 *
 * @author songqi(13776346982)(13776346982)
 */
public class BaseController
{
    protected final Logger logger = LoggerFactory.getLogger(this.getClass());


    @Resource
    private TokenService tokenService;

    public BaseController() {
    }


    protected LoginUser getLoginUser(){
        return tokenService.getLoginUser(ServletUtils.getRequest());
    }


    protected TokenUser getTokenUser(){
        return this.getLoginUser().getTokenUser();
    }



    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
            @Override
            public void setAsText(String text) {
                this.setValue(DateUtil.parseDate(text));
            }
        });
    }

    protected void startPage() {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlStrUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }

    }

    protected void startPage(PageDomain pageDomain) {
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize = pageDomain.getPageSize();
        if (StringUtils.isNotNull(pageNum) && StringUtils.isNotNull(pageSize)) {
            String orderBy = SqlStrUtil.escapeOrderBySql(pageDomain.getOrderBy());
            PageHelper.startPage(pageNum, pageSize, orderBy);
        }
    }

    protected String getLanguage() {
        return LocaleContextHolder.getLocale().getLanguage();
    }



    /**
     * 返回一个只有分页数据的空对象
     * @param page
     * @return
     */
    public PageDataInfo getDataTableInfoWithoutRows(IPage page){
        PageDataInfo tableDataInfo = new PageDataInfo<>();
        tableDataInfo.setPageNum(page.getCurrent());
        tableDataInfo.setTotal(page.getTotal());
        tableDataInfo.setPageSize(page.getSize());
        tableDataInfo.setMaxPage(page.getPages());
        return tableDataInfo;
    }

    protected R<PageDataInfo> getDataTable(List list) {
        PageDataInfo rspData = new PageDataInfo<>();
        rspData.setCode(200);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal((new PageInfo(list)).getTotal());
        return R.success(rspData);
    }



    protected <T> R<PageDataInfo<T>> getReturnDataTableInfo(IPage<T> page) {
        PageDataInfo<T> rspData = new PageDataInfo<>();
        rspData.setPageNum(page.getCurrent());
        rspData.setTotal(page.getTotal());
        rspData.setRows(page.getRecords());
        rspData.setPageSize(page.getSize());
        rspData.setMaxPage(page.getPages());
        return R.success(rspData);
    }

    protected <T> R<PageDataInfo<T>> getReturnDataTableInfo(IPage<?> page, Class<T> target) {
        PageDataInfo<T> rspData = new PageDataInfo<>();
        rspData.setPageNum(page.getCurrent());
        rspData.setTotal(page.getTotal());
        rspData.setRows(BeanCopyUtil.copyList(page.getRecords(), target));
        rspData.setPageSize(page.getSize());
        rspData.setMaxPage(page.getPages());
        return R.success(rspData);
    }

    protected <T> R<T> toAjax(int rows) {
        return rows > 0 ? R.success() : R.error();
    }

    protected <T> R<T> toAjax(boolean result) {
        return result ? this.success() : this.error();
    }

    public <T> R<T> success() {
        return R.success();
    }

    public <T> R<T> error() {
        return R.error();
    }

    public <T> R<T> success(T data) {
        return R.success(data);
    }

    public <T> R<T> error(String message) {
        return R.error(message);
    }

    public String redirect(String url) {
        return StringUtils.format("redirect:{}", new Object[]{url});
    }


    /**
     * 生成二维码
     * @param text
     * @param response
     * @throws IOException
     */
    public void createQrCode(String text, int width, int height, HttpServletResponse response) throws IOException {
        if(width == 0){
            width = 300;
        }
        if(height == 0){
            height = 300;
        }
        BufferedImage bufferedImage = QrCodeUtil.generate(text, width, height);
        OutputStream outputStream = response.getOutputStream();
        ImageIO.write(bufferedImage, "png", outputStream);
        outputStream.flush();
        outputStream.close();
    }

    /**
     * 生成条形码
     * @param text
     * @param response
     * @throws IOException
     */
    public void createBarCode(String text, int width, int height, HttpServletResponse response) throws IOException {
        if(width == 0){
            width = 312;
        }
        if(height == 0) {
            height = 100;
        }
        BufferedImage bufferedImage = QrCodeUtil.generate(text, BarcodeFormat.CODE_128, width, height);
        OutputStream outputStream = response.getOutputStream();
        ImageIO.write(bufferedImage, "png", outputStream);
        outputStream.flush();
        outputStream.close();
    }


    public OutputStream getDownloadOutputStream(HttpServletResponse response, String fileName, String contentType) throws IOException {
        OutputStream out = response.getOutputStream();
        response.setContentType(contentType);
        response.addHeader("Access-Control-Expose-Headers","Content-Type,Content-Disposition,Pargam,Cache-Control");
        response.setHeader("content-disposition","attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        response.addHeader("Pargam", "no-cache");
        response.addHeader("Cache-Control", "no-cache");
        return out;

    }

    public OutputStream getPreviewOutputStream(HttpServletResponse response, String contentType) throws IOException {
        response.setContentType(contentType);
        response.addHeader("Content-Disposition", "inline");
        response.addHeader("Pargam", "no-cache");
        response.addHeader("Cache-Control", "no-cache");
        return response.getOutputStream();

    }

    public void preview(HttpServletResponse response, String contentType, InputStream in) {
        OutputStream out = null;
        try {
            out = getPreviewOutputStream(response, contentType);
            byte[] b = new byte[2048];
            int length;
            while ((length = in.read(b)) > 0) {
                out.write(b, 0, length);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(out != null){
                    out.close();
                }
                if(in != null){
                    in.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
